﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Media;
using WPNextTools.NConstant;
using WPNextTools.NHelper;
using System.IO;
using Microsoft.Xna.Framework.Audio;
using System.Windows.Resources;
using System.Diagnostics;

namespace WPNextTools.NControls
{
    public class ExplodePhotoListBoxItem : PhotoListBoxItem
    {
        #region Fields
        private Image deleteImage;
        private SeqPlayImg seqPlayImg;
        private ItemState currentItemState;
        internal bool preparedToExplode = false;
        #endregion

        #region Properties
        internal ItemState ItemState
        {
            get
            {
                return this.currentItemState;
            }
        }        
        #endregion

        #region Override
        protected override void OnAttached()
        {
            base.OnAttached();
            this.deleteImage = new Image();
            this.deleteImage.MouseLeftButtonDown += OnItemDeleteImageClicked;
            seqPlayImg = new SeqPlayImg();
            seqPlayImg.ImageFolder = ((ExplodePhotoListBox)this.owner).explodeFolderCache;
        }

        protected override void OnDetached()
        {
            base.OnDetached();
            if (this.deleteImage != null)
            {
                this.deleteImage.MouseLeftButtonDown -= OnItemDeleteImageClicked;
                this.deleteImage = null;
            }
            if (seqPlayImg != null)
            {
                seqPlayImg = null;
            }
        }

        protected override void OnHold(GestureEventArgs e)
        {
            if (this.owner is ExplodePhotoListBox)
            {
                ((ExplodePhotoListBox)owner).OnItemHold(this);
            }
        }

        protected override void OnTap(GestureEventArgs e)
        {
            if (!preparedToExplode)
            {
                base.OnTap(e);
            }
        }
        #endregion

        #region Method
        protected virtual void OnItemDeleteImageClicked(object sender, MouseButtonEventArgs e)
        {
            this.deleteImage.MouseLeftButtonDown -= OnItemDeleteImageClicked;
            Image image = this.GetFirstLogicalChildByType<Image>(true);
            BitmapImage bitmapImage = (image.Source as BitmapImage);
            if (bitmapImage == null || bitmapImage.PixelWidth == 0 || bitmapImage.PixelHeight == 0)
            {
                e.Handled = true;
                return;
            }
            //byte[] b = BitmapImageToByte(bitmapImage);
            //Debug.WriteLine(b.Length);

            if (base.owner != null)
            {
                //播放爆炸声音
                ((ExplodePhotoListBox)this.owner).ambienceSound.Play();
                //播放爆炸效果
                Panel panel = this.GetFirstLogicalChildByType<Panel>(true);
                panel.Children.Add(seqPlayImg);
                Storyboard st = PlayExplod();
                //冻结呈现出来的底部bottom
                ((ExplodePhotoListBox)owner).FreezeBottom();
                st.Completed += (s, ev) =>
                {
                    RemoveDeleteImage();
                    panel.Children.Remove(seqPlayImg);
                    ((ExplodePhotoListBox)owner).UnFreezeBottom();
                    ((ExplodePhotoListBox)owner).OnDeleteImageClick();
                };
            }
        }

        public byte[] BitmapImageToByte(BitmapImage bitmapImage)
        {
            byte[] data;
            // Get an Image Stream
            using (MemoryStream ms = new MemoryStream())
            {

                WriteableBitmap btmMap = new WriteableBitmap(bitmapImage);

                // write an image into the stream

                Extensions.SaveJpeg(btmMap, ms, bitmapImage.PixelWidth, bitmapImage.PixelHeight, 0, 100);

                // reset the stream pointer to the beginning
                ms.Seek(0, 0);
                //read the stream into a byte array
                data = new byte[ms.Length];
                ms.Read(data, 0, data.Length);
            }
            //data now holds the bytes of the image
            return data;
        }

      
        /// <summary>
        /// 播放爆炸效果
        /// </summary>
        /// <returns></returns>
        private Storyboard PlayExplod()
        {
            Storyboard st = new Storyboard();
            DoubleAnimationUsingKeyFrames da = new DoubleAnimationUsingKeyFrames();
            EasingDoubleKeyFrame ed = new EasingDoubleKeyFrame { KeyTime = TimeSpan.FromMilliseconds(0), Value = 1 };
            EasingDoubleKeyFrame ed2 = new EasingDoubleKeyFrame { KeyTime = TimeSpan.FromMilliseconds(1000), Value = 18 };
            da.KeyFrames.Add(ed);
            da.KeyFrames.Add(ed2);

            Storyboard.SetTarget(da, this.seqPlayImg);
            Storyboard.SetTargetProperty(da, new PropertyPath("(ImageSequence.CurrentImgNum)"));

            st.Children.Add(da);
            st.Begin();
            return st;
        }

        private Panel GetFirstPanel()
        {
            Panel panel = this.GetFirstLogicalChildByType<Panel>(true);
            return panel;
        }

        internal virtual void AddDeleteImage()
        {
            string deleteIcon = ((ExplodePhotoListBox)base.owner).deleteIconCache;
            deleteImage.Source = new BitmapImage(new Uri(deleteIcon, UriKind.RelativeOrAbsolute));
            deleteImage.Stretch = Stretch.None;
            deleteImage.VerticalAlignment = VerticalAlignment.Top;
            deleteImage.HorizontalAlignment = HorizontalAlignment.Left;

            deleteImage.Margin = new Thickness(this.associatedDataItem.X + this.associatedDataItem.Width - (double)(32 / 2), this.associatedDataItem.Y - (double)(46 / 2), 0, 0);
            
            Panel panel = this.owner.scrollableContent;
            if (panel.Children.Contains(deleteImage))
            {
                panel.Children.Remove(deleteImage);
            }
            panel.Children.Add(deleteImage);
            preparedToExplode = true;//准备爆炸
        }

        internal virtual void RemoveDeleteImage()
        {
            Panel panel = this.owner.scrollableContent;
            if (panel.Children.Contains(deleteImage))
            {
                panel.Children.Remove(deleteImage);
            }
            preparedToExplode = false;//取消准备爆炸
        }
        #endregion
        
        #region State
        internal void GoToToppedState()
        {
            if (this.currentItemState == ItemState.Bottomed)
            {
                this.Opacity = 1;
            }
            this.currentItemState = ItemState.Topped;
            SetHorizontalOffset(this.associatedDataItem.X - 10);
            SetVerticalOffset(this.associatedDataItem.Y - 10);
            SetZIndex(1);
            this.Width += 20;
            this.Height += 20;
            AddDeleteImage();
        }

        internal void GoToBottomState()
        {
            if (this.currentItemState == ItemState.Topped)
            {
                SetHorizontalOffset(this.associatedDataItem.X);
                SetVerticalOffset(this.associatedDataItem.Y);
                SetZIndex(0);
                this.Width -= 20;
                this.Height -= 20;
                RemoveDeleteImage();
            }
            this.currentItemState = ItemState.Bottomed;
            this.Opacity = 0.6;
        }

        internal void BackToNormal()
        {
            if (this.currentItemState == ItemState.Bottomed)
            {
                this.Opacity = 1;
            }
            else if (this.currentItemState == ItemState.Topped)
            {
                SetHorizontalOffset(this.associatedDataItem.X);
                SetVerticalOffset(this.associatedDataItem.Y);
                SetZIndex(0);
                this.Width -= 20;
                this.Height -= 20;
                RemoveDeleteImage();
            }
            this.currentItemState = ItemState.Realized;
        }

        #endregion

        private void LoadSound(string soundFilePath, out SoundEffect sound)
        {
            sound = null;
            try
            {
                StreamResourceInfo soundFileInfo = Application.GetResourceStream(new Uri(soundFilePath, UriKind.RelativeOrAbsolute));
                sound = SoundEffect.FromStream(soundFileInfo.Stream);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("Couldn't load sound " + soundFilePath);
            }
        }
    }
}
